package com.boot.stomp;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.boot.security.mapper.UserMapper;
import com.boot.security.model.dto.LoginAccount;
import com.boot.security.model.po.User;
import com.boot.stomp.authentication.StompAuthenticationHandler;
import com.sun.security.auth.UserPrincipal;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.security.Principal;

public class LoginAuthenticationHandler implements StompAuthenticationHandler {

    private final UserMapper userMapper;
    private final PasswordEncoder encoder;

    public LoginAuthenticationHandler(UserMapper userMapper, PasswordEncoder encoder) {
        this.userMapper = userMapper;
        this.encoder = encoder;
    }


    @Override
    public Principal getPrincipal(StompHeaderAccessor accessor) {
        String principal = accessor.getFirstNativeHeader("principal");
        String credential = accessor.getFirstNativeHeader("credential");

        int type = 1;
        if (principal != null && credential != null) {
            String typeString = accessor.getFirstNativeHeader("type");
            if (typeString != null) {
                try {
                    type = Integer.parseInt(typeString);
                } catch (NumberFormatException ignore) {
                }
            }
            User authUser = new User();
            switch (type) {
                case LoginAccount.USERNAME_PASSWORD:
                    authUser.setUsername(principal);
                    break;
                case LoginAccount.PHONE_PASSWORD:
                    authUser.setPhone(principal);
                    break;
                case LoginAccount.EMAIL_PASSWORD:
                    authUser.setEmail(principal);
                    break;
                default:
                    throw new AuthenticationServiceException("登录方式错误");
            }
            User user = userMapper.selectOne(Wrappers.query(authUser));
            if (user == null) {
                throw new UsernameNotFoundException("没有找到该用户");
            } else {
                if (user.getStatus() == 0) {
                    // 账户正常
                    if (encoder.matches(credential, user.getPassword())) {
                        return new UserPrincipal(user.getUsername());
                    } else {
                        throw new BadCredentialsException("密码错误");
                    }
                } else {
                    // 账户禁用
                    throw new LockedException("账户禁用");
                }
            }
        } else {
            return null;
        }
    }
}
